package com.xfyang.common.dataSource.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.xfyang.common.annotation.Read;
import com.xfyang.common.annotation.Write;
import com.xfyang.common.dataSource.DynamicDataSourceHolder;

@Component
@Aspect
public class DataSourceAspect {
    
	//private final Logger log = LoggerFactory.getLogger(DataSourceAspect.class);
	private static final String READ = "read";
	private static final String WRITE = "write";

	/*
	 * @Before("execution(* com.xfyang.service.impl.*.*(..))") public void
	 * before(JoinPoint point) {
	 * 
	 * System.out
	 * .println("*************************before*************************");
	 * Object target = point.getTarget(); String method =
	 * point.getSignature().getName();
	 * 
	 * Class<?> clazz = target.getClass();; Class<?>[] parameterTypes =
	 * ((MethodSignature) point.getSignature())
	 * .getMethod().getParameterTypes();
	 * 
	 * try { Method m = clazz.getMethod(method, parameterTypes); if (m != null)
	 * { if (m.isAnnotationPresent(Read.class)) {
	 * DynamicDataSourceHolder.putDataSource(READ); } else if
	 * (m.isAnnotationPresent(Write.class)) {
	 * DynamicDataSourceHolder.putDataSource(WRITE); } else {
	 * DynamicDataSourceHolder.putDataSource(WRITE); } } } catch
	 * (NoSuchMethodException e) { e.printStackTrace(); } catch
	 * (SecurityException e) { e.printStackTrace(); }
	 * 
	 * }
	 */

	@Around(value = "execution(* com.xfyang.service.impl.*.*(..)) && @annotation(read)")
	public Object aroundRead(ProceedingJoinPoint pjd, Read read) {
		try {
			if (getMethod(pjd) != null) {
				DynamicDataSourceHolder.putDataSource(READ);
			}

			return pjd.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			DynamicDataSourceHolder.clearCustomerType();
		}

		return null;
	}

	@Around(value = "execution(* com.xfyang.service.impl.*.*(..)) && @annotation(write)")
	public Object aroundRead(ProceedingJoinPoint pjd, Write write) {
		try {
			System.out
					.println("*************************write*************************");
			if (getMethod(pjd) != null) {
				DynamicDataSourceHolder.putDataSource(WRITE);
			}

			return pjd.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			DynamicDataSourceHolder.clearCustomerType();
		}
		return null;
	}

	/**
	 * @Title: getMethod 
	 * @Description: 
	 * @param pjd
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @return Method
	 * @version V1.0
	 * @author xfyang
	 * @Date 2016年7月24日 下午11:05:45
	 */
	private Method getMethod(ProceedingJoinPoint pjd)
			throws NoSuchMethodException, SecurityException {
		Object target = pjd.getTarget();
		String method = pjd.getSignature().getName();
		Class<?> clazz = target.getClass();
		Class<?>[] parameterTypes = ((MethodSignature) pjd.getSignature())
				.getMethod().getParameterTypes();
		Method m = clazz.getMethod(method, parameterTypes);
		return m;
	}
}
